namespace C1.Win.C1FlexGrid.Util.Styles
{
    using System;
    using System.Collections;
    using System.Drawing;

    internal class Style
    {
        internal Hashtable _atts;
        internal StyleContext _context;
        internal string _name;
        internal Style _parent;

        private Style(StyleContext context, Style parent)
        {
            this._context = context;
            this._parent = parent;
            this._atts = new Hashtable();
        }

        public Style(StyleContext context, string name, Style parent)
        {
            if (context == null)
            {
                throw new ArgumentException("Invalid context");
            }
            if (((name == null) || (name.Length == 0)) || context.HasStyle(name))
            {
                throw new ArgumentException("Invalid name");
            }
            if ((parent != null) && (parent.GetContext() != context))
            {
                throw new ArgumentException("Invalid parent style");
            }
            this._context = context;
            this._parent = parent;
            this._atts = new Hashtable();
            this._name = name;
        }

        public void Clear()
        {
            this._atts.Clear();
            this._context.NotifyChange(this);
        }

        public Style Clone()
        {
            return new Style(this._context, this);
        }

        public object GetAttribute(string name)
        {
            object obj2 = this._atts[name];
            if (obj2 != null)
            {
                return obj2;
            }
            if (this._parent != null)
            {
                return this._parent.GetAttribute(name);
            }
            return this._context.GetBaseStyle()._atts[name];
        }

        public ICollection GetAttributes()
        {
            return this._atts.Keys;
        }

        public Rectangle GetContentRectangle(Rectangle r)
        {
            return this._context.GetContentRectangle(this, r);
        }

        public StyleContext GetContext()
        {
            return this._context;
        }

        public virtual int GetHeight(Graphics g, int wid, Image img)
        {
            return this._context.GetHeight(this, g, wid, null, img);
        }

        public virtual int GetHeight(Graphics g, int wid, string str)
        {
            return this._context.GetHeight(this, g, wid, str, null);
        }

        public virtual int GetHeight(Graphics g, int wid, string str, Image img)
        {
            return this._context.GetHeight(this, g, wid, str, img);
        }

        public Rectangle GetImageRectangle(Rectangle r, Image img)
        {
            return this._context.GetImageRectangle(this, r, img);
        }

        public string GetName()
        {
            return this._name;
        }

        public Style GetParent()
        {
            return this._parent;
        }

        public Rectangle GetTextRectangle(Rectangle r, Image img)
        {
            return this._context.GetTextRectangle(this, r, img);
        }

        public virtual int GetWidth(Graphics g, Image img)
        {
            return this._context.GetWidth(this, g, null, img);
        }

        public virtual int GetWidth(Graphics g, string str)
        {
            return this._context.GetWidth(this, g, str, null);
        }

        public virtual int GetWidth(Graphics g, string str, Image img)
        {
            return this._context.GetWidth(this, g, str, img);
        }

        public bool HasAttribute(string name)
        {
            return this._atts.Contains(name);
        }

        public bool IsEmpty()
        {
            return (this._atts.Count == 0);
        }

        public void RemoveAttribute(string name)
        {
            this._atts.Remove(name);
            this._context.NotifyChange(this);
        }

        public virtual void Render(Graphics g, Rectangle rc, Image img)
        {
            this.Render(g, rc, null, img, RenderFlags.All);
        }

        public virtual void Render(Graphics g, Rectangle rc, string str)
        {
            this.Render(g, rc, str, null, RenderFlags.All);
        }

        public virtual void Render(Graphics g, Rectangle rc, string str, Image img)
        {
            this.Render(g, rc, str, img, RenderFlags.All);
        }

        public virtual void Render(Graphics g, Rectangle rc, string str, Image img, RenderFlags flags)
        {
            this._context.Render(this, g, rc, str, img, flags);
        }

        public virtual void RenderContent(Graphics g, Rectangle rc, string str, Image img)
        {
            this._context.RenderContent(this, g, rc, str, img);
        }

        public void SetAttribute(string name, object attVal)
        {
            if ((this._context.GetBaseStyle() == this) && !this._atts.Contains(name))
            {
                this._atts.Add(name, attVal);
                this._context.NotifyChange(this);
            }
            else
            {
                object attribute = this._context.GetBaseStyle().GetAttribute(name);
                if (attribute == null)
                {
                    throw new ArgumentException("Attribute '" + name + "' not defined in base style");
                }
                if ((attVal != null) && !attribute.GetType().IsAssignableFrom(attVal.GetType()))
                {
                    throw new ArgumentException("Incompatible attribute value for '" + name + "'");
                }
                this._atts[name] = attVal;
                this._context.NotifyChange(this);
            }
        }

        public void SetAttributeIfNeeded(string name, object attVal)
        {
            if (this._context.GetBaseStyle() == this)
            {
                this.SetAttribute(name, attVal);
            }
            else
            {
                if (this.HasAttribute(name))
                {
                    this.RemoveAttribute(name);
                }
                object attribute = this.GetAttribute(name);
                if (attribute == null)
                {
                    throw new ArgumentException("Attribute '" + name + "' not defined in base style");
                }
                if (!attribute.Equals(attVal))
                {
                    this.SetAttribute(name, attVal);
                }
            }
        }

        public bool SetName(string newName)
        {
            return this._context.RenameStyle(this, newName);
        }

        public Style SetParent(Style parent)
        {
            return this.SetParent(parent, true);
        }

        public Style SetParent(Style parent, bool notify)
        {
            parent = this.ValidateParent(parent);
            this._parent = parent;
            if (notify)
            {
                this._context.NotifyChange(this);
            }
            return this;
        }

        public override string ToString()
        {
            return ("{Style: " + this.GetName() + "}");
        }

        private Style ValidateParent(Style parent)
        {
            if (parent == null)
            {
                return null;
            }
            if (parent.GetContext() != this.GetContext())
            {
                return null;
            }
            for (Style style = parent; style != null; style = style.GetParent())
            {
                if (style == this)
                {
                    return null;
                }
            }
            return parent;
        }
    }
}

